using System;
using GammaJul.ReSharper.GammaXaml.Highlightings.CSharp;
using JetBrains.Annotations;
using JetBrains.DocumentModel;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Daemon.Impl;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.Tree;

[assembly: RegisterConfigurableSeverity(
	MismatchedDpDefaultValueTypeHighlighting.SeverityId,
	null,
	HighlightingGroupIds.CodeSmell,
	MismatchedDpDefaultValueTypeHighlighting.Description,
	MismatchedDpDefaultValueTypeHighlighting.Description,
	Severity.ERROR,
	false)]

namespace GammaJul.ReSharper.GammaXaml.Highlightings.CSharp {

	/// <summary>
	/// An highlighting that represent a wrong default value for a dependency property.
	/// </summary>
	[ConfigurableSeverityHighlighting(SeverityId, CSharpProjectFileType.Name, OverlapResolve = OverlapResolveKind.ERROR)]
	public class MismatchedDpDefaultValueTypeHighlighting : IHighlightingWithRange {
		internal const string SeverityId = "Dp.MismatchedDpDefaultValueType";
		internal const string Description = "Dependency property default value type doesn't match its property type.";
		
		private readonly IArgument _defaultValueArgument;
		private readonly IType _dpRegisteredType;
		
		/// <summary>
		/// Gets the default value argument.
		/// </summary>
		[NotNull]
		public IArgument DefaultValueArgument {
			get { return _defaultValueArgument; }
		}

		/// <summary>
		/// Gets the dependency property registered type.
		/// </summary>
		[NotNull]
		public IType DpRegisteredType {
			get { return _dpRegisteredType; }
		}

		public string ToolTip {
			get { return Description; }
		}

		public string ErrorStripeToolTip {
			get { return Description; }
		}

		public int NavigationOffsetPatch {
			get { return 0; }
		}

		public bool IsValid() {
			return _defaultValueArgument.IsValid() && _dpRegisteredType.IsValid();
		}

		public DocumentRange CalculateRange() {
			return _defaultValueArgument.GetDocumentRange();
		}

		public MismatchedDpDefaultValueTypeHighlighting([NotNull] IArgument defaultValueArgument, [NotNull] IType dpRegisteredType) {
			if (defaultValueArgument == null)
				throw new ArgumentNullException("defaultValueArgument");
			if (dpRegisteredType == null)
				throw new ArgumentNullException("dpRegisteredType");

			_defaultValueArgument = defaultValueArgument;
			_dpRegisteredType = dpRegisteredType;
		}
	}

}
